Implement gtk-primary-button-warps-slider GtkSetting
authorKristian Rietveld <kris@lanedo.com>
Fri, 24 Aug 2012 09:49:43 +0000 (11:49 +0200)
committerMichael Natterer <mitch@gimp.org>
Tue, 11 Sep 2012 09:19:09 +0000 (11:19 +0200)
Make GtkRange honor the setting and implement it in the
quartz backend, it proxies the "click in the scroll bar to"
property from the OS X PrefPane.

gdk/quartz/gdkevents-quartz.c
gtk/gtkrange.c
gtk/gtksettings.c

index b2ecb1a31f2ac0a36a141d050c89603dc3626324..712f23245a88e22f6f23fb23e1c7f581ab92742a 100644 (file)
@@ -58,10 +58,62 @@ static GdkWindow *find_toplevel_under_pointer   (GdkDisplay *display,
                                                  gint       *y);
 
 
+static void
+gdk_quartz_ns_notification_callback (CFNotificationCenterRef  center,
+                                     void                    *observer,
+                                     CFStringRef              name,
+                                     const void              *object,
+                                     CFDictionaryRef          userInfo)
+{
+  GdkEvent new_event;
+
+  new_event.type = GDK_SETTING;
+  new_event.setting.window = gdk_screen_get_root_window (_gdk_screen);
+  new_event.setting.send_event = FALSE;
+  new_event.setting.action = GDK_SETTING_ACTION_CHANGED;
+  new_event.setting.name = NULL;
+
+  /* Translate name */
+  if (CFStringCompare (name,
+                       CFSTR("AppleNoRedisplayAppearancePreferenceChanged"),
+                       0) == kCFCompareEqualTo)
+    new_event.setting.name = "gtk-primary-button-warps-slider";
+
+  if (!new_event.setting.name)
+    return;
+
+  gdk_event_put (&new_event);
+}
+
+static void
+gdk_quartz_events_init_notifications (void)
+{
+  static gboolean notifications_initialized = FALSE;
+
+  if (notifications_initialized)
+    return;
+  notifications_initialized = TRUE;
+
+  /* Initialize any handlers for notifications we want to push to GTK
+   * through GdkEventSettings.
+   */
+
+  /* This is an undocumented *distributed* notification to listen for changes
+   * in scrollbar jump behavior. It is used by LibreOffice and WebKit as well.
+   */
+  CFNotificationCenterAddObserver (CFNotificationCenterGetDistributedCenter (),
+                                   NULL,
+                                   &gdk_quartz_ns_notification_callback,
+                                   CFSTR ("AppleNoRedisplayAppearancePreferenceChanged"),
+                                   NULL,
+                                   CFNotificationSuspensionBehaviorDeliverImmediately);
+}
+
 void
 _gdk_quartz_events_init (void)
 {
   _gdk_quartz_event_loop_init ();
+  gdk_quartz_events_init_notifications ();
 
   current_keyboard_window = g_object_ref (_gdk_root);
 }
@@ -1550,6 +1602,19 @@ _gdk_quartz_screen_get_setting (GdkScreen   *screen,
 
       GDK_QUARTZ_RELEASE_POOL;
 
+      return TRUE;
+    }
+  else if (strcmp (name, "gtk-primary-button-warps-slider") == 0)
+    {
+      GDK_QUARTZ_ALLOC_POOL;
+
+      BOOL setting = [[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollerPagingBehavior"];
+
+      /* If the Apple property is YES, it means "warp" */
+      g_value_set_boolean (value, setting == YES);
+
+      GDK_QUARTZ_RELEASE_POOL;
+
       return TRUE;
     }
   
index 529a8d76a96a4ce5f698e26b27731ee1fb3e18ea..d18cf2bbac9aa5415374137eb6563d5010db951f 100644 (file)
@@ -2522,6 +2522,8 @@ gtk_range_button_press (GtkWidget      *widget,
   GtkRangePrivate *priv = range->priv;
   GdkDevice *device, *source_device;
   GdkInputSource source;
+  gboolean primary_warps;
+  gint page_increment_button, warp_button;
 
   if (!gtk_widget_has_focus (widget))
     gtk_widget_grab_focus (widget);
@@ -2540,6 +2542,20 @@ gtk_range_button_press (GtkWidget      *widget,
   if (gtk_range_update_mouse_location (range))
     gtk_widget_queue_draw (widget);
 
+  g_object_get (gtk_widget_get_settings (widget),
+                "gtk-primary-button-warps-slider", &primary_warps,
+                NULL);
+  if (primary_warps)
+    {
+      warp_button = GDK_BUTTON_PRIMARY;
+      page_increment_button = GDK_BUTTON_SECONDARY;
+    }
+  else
+    {
+      warp_button = GDK_BUTTON_MIDDLE;
+      page_increment_button = GDK_BUTTON_PRIMARY;
+    }
+
   if (priv->mouse_location == MOUSE_SLIDER &&
       gdk_event_triggers_context_menu ((GdkEvent *)event))
     {
@@ -2552,7 +2568,7 @@ gtk_range_button_press (GtkWidget      *widget,
 
   if (source != GDK_SOURCE_TOUCHSCREEN &&
       priv->mouse_location == MOUSE_TROUGH &&
-      event->button == GDK_BUTTON_SECONDARY)
+      event->button == page_increment_button)
     {
       /* button 2 steps by page increment, as with button 2 on a stepper
        */
@@ -2603,7 +2619,7 @@ gtk_range_button_press (GtkWidget      *widget,
     }
   else if ((priv->mouse_location == MOUSE_TROUGH &&
             (source == GDK_SOURCE_TOUCHSCREEN ||
-             event->button == GDK_BUTTON_PRIMARY)) ||
+             event->button == warp_button)) ||
            priv->mouse_location == MOUSE_SLIDER)
     {
       gboolean need_value_update = FALSE;
index 534ef021c52e071f0a9d48f6671707cadf5b8c56..cac82bd99959530d3086eb4ab0fde5abbb03753b 100644 (file)
@@ -193,6 +193,7 @@ enum {
   PROP_TOOLBAR_STYLE,
   PROP_TOOLBAR_ICON_SIZE,
   PROP_AUTO_MNEMONICS,
+  PROP_PRIMARY_BUTTON_WARPS_SLIDER,
   PROP_VISIBLE_FOCUS,
   PROP_APPLICATION_PREFER_DARK_THEME,
   PROP_BUTTON_IMAGES,
@@ -1144,6 +1145,23 @@ gtk_settings_class_init (GtkSettingsClass *class)
                                              NULL);
   g_assert (result == PROP_AUTO_MNEMONICS);
 
+  /**
+   * GtkSettings:gtk-primary-button-warps-slider
+   *
+   * Whether a click in a #GtkRange trough should scroll to the click position or
+   * scroll by a single page in the respective direction.
+   *
+   * Since: 2.24
+   */
+  result = settings_install_property_parser (class,
+                                             g_param_spec_boolean ("gtk-primary-button-warps-slider",
+                                                                   P_("Primary button warps slider"),
+                                                                   P_("Whether a primary click on the trough should warp the slider into position"),
+                                                                   TRUE,
+                                                                   GTK_PARAM_READWRITE),
+                                             NULL);
+  g_assert (result == PROP_PRIMARY_BUTTON_WARPS_SLIDER);
+
   /**
    * GtkSettings:gtk-visible-focus:
    *